package com.suhui.task.service;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.*;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


@Service
public class HttpRequest {

    /**
     * 通过GET方式发起http请求
     */
    public String sendGet(String url){return sendGet(url,null,null);}
    public String sendGet(String url,Map<String,Object> param){return sendGet(url,param,null);}
    public String sendGet(String url, Map<String,Object> param, Map<String,String> header){
        String result = null;
        String URl=url;
        //创建默认的httpClient实例
        if (param!=null) {
            URl=url+"?";
            for (Map.Entry<String, Object> entry : param.entrySet()) {
                URl = URl+entry.getKey()+"="+entry.getValue()+"&";
            }
            URl=URl.substring(0,URl.length()-1);
        }
        CloseableHttpClient httpClient = getHttpClient();
        try {
            //用get方法发送http请求
            HttpGet get = new HttpGet(URl);
            //请求头
            if (header!=null) {
                for (Map.Entry<String, String> entry : header.entrySet()) {
                    get.addHeader(entry.getKey(), entry.getValue());
                }
            }
            CloseableHttpResponse httpResponse;
            //发送get请求
            httpResponse = httpClient.execute(get);
            try{
                //response实体
                HttpEntity entity = httpResponse.getEntity();
                if (null != entity){
                    result =  EntityUtils.toString(entity);
                }
            }
            finally{
                httpResponse.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        finally{
            try{
                closeHttpClient(httpClient);
            } catch (IOException e){
                e.printStackTrace();
            }
        }
        return result;
    }
    /**
     * 通过GET方式发起http请求
     * header为空获取所有请求头
     * header不为空获取特定响应头
     */
    public Map<String,Object> sendGet_gethead(String url){return sendGet_gethead(url,null,null,null);}
    public Map<String,Object> sendGet_gethead(String url,String header){return sendGet_gethead(url,header,null,null);}
    public Map<String,Object> sendGet_gethead(String url,String header, Map<String,Object> param){return sendGet_gethead(url,header,param,null);}
    public Map<String,Object> sendGet_gethead(String url,String header, Map<String,Object> param, Map<String,String> headers){
        String result = null;
        String URl=url;
        Map<String,Object> re=new HashMap<>();
        //创建默认的httpClient实例
        if (param!=null) {
            for (Map.Entry<String, Object> entry : param.entrySet()) {
//                get.addHeader(entry.getKey(), entry.getValue());
                URl = url+"?"+entry.getKey()+"="+entry.getValue()+"&";
            }
            URl=URl.substring(0,URl.length()-1);
        }
        CloseableHttpClient httpClient = getHttpClient();
        try {
            //用get方法发送http请求
            HttpGet get = new HttpGet(URl);
            if (headers!=null) {
                for (String key : headers.keySet()) {
                    get.addHeader(new BasicHeader(key, headers.get(key)));
                }
            }
            CloseableHttpResponse httpResponse;
            //发送get请求
            httpResponse = httpClient.execute(get);
            try{
                //response实体
                HttpEntity entity = httpResponse.getEntity();
                if (null != entity){
                    result =  EntityUtils.toString(entity);
                }
                if (header!=null){
                    Header response_header = httpResponse.getFirstHeader(header);
                    re.put(header,response_header);
                }else {
                    Header[] allHeaders = httpResponse.getAllHeaders();
                    for (int i = 0; i < allHeaders.length; i++) {
                        re.put(allHeaders[i].getName(),allHeaders[i].getValue());
                    }
                }
            }
            finally{
                httpResponse.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        finally{
            try{
                closeHttpClient(httpClient);
            } catch (IOException e){
                e.printStackTrace();
            }
        }
        re.put("data",result);
        return re;
    }
    /**
     *  POST方式发起http请求
     *  设置json格式参数
     * @return strResult
     */
    public String sendPost_json(String url){return sendPost_json(url,null,null);}
    public String sendPost_json(String url,Map<String, Object> param){return sendPost_json(url,param,null);}
    public String sendPost_json(String url, Map<String, Object> param, Map<String,String> header){
        String strResult = "";
        // 1. 获取默认的client实例
        CloseableHttpClient client = HttpClients.createDefault();
        // 2. 创建httppost实例
        HttpPost post = new HttpPost(url);
        if (header!=null) {
            for (String key : header.keySet()) {
                post.addHeader(new BasicHeader(key, header.get(key)));
            }
        }
        post.addHeader("Content-Type", "application/json;charset=utf-8"); //添加请求头
        try {
            post.setEntity(new StringEntity(JSON.toJSONString(param),"utf-8"));
            CloseableHttpResponse resp = client.execute(post);
            try {
                // 7. 获取响应entity
                HttpEntity respEntity = resp.getEntity();
                strResult = EntityUtils.toString(respEntity, "UTF-8");
            } finally {
                resp.close();
            }
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                client.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return strResult;
    }

    /**
     * 以json格式的字符串参数方式发起请求
     * @param url url地址
     * @param param json格式的String类型参数
     * @param header 请求头信息
     * @return String 返回响应信息
     */
    public String sendPost_json_(String url, String param, Map<String,String> header){
        String strResult = "";
        // 1. 获取默认的client实例
        CloseableHttpClient client = HttpClients.createDefault();
        // 2. 创建httppost实例
        HttpPost post = new HttpPost(url);
        if (header!=null) {
            for (String key : header.keySet()) {
                post.addHeader(new BasicHeader(key, header.get(key)));
            }
        }
        post.addHeader("Content-Type", "application/json;charset=utf-8"); //添加请求头
        try {
            post.setEntity(new StringEntity(param,"utf-8"));
            CloseableHttpResponse resp = client.execute(post);
            try {
                // 7. 获取响应entity
                HttpEntity respEntity = resp.getEntity();
                strResult = EntityUtils.toString(respEntity, "UTF-8");
            } finally {
                resp.close();
            }
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                client.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return strResult;
    }
    /**
     * POST方式发起http请求
     * 设置url格式参数
     */
    public String sendPost_url(String url){return sendPost_url(url,null,null);}
    public String sendPost_url(String url,Map<String, Object> param){return sendPost_url(url,param,null);}
    public String sendPost_url(String url, Map<String, Object> param, Map<String,String> header){
        String result = null;
        CloseableHttpClient httpClient = getHttpClient();
        try {
            HttpPost post = new HttpPost(url);
            //添加请求头,和请求体
            if (header!=null) {
                for (String key : header.keySet()) {
                    post.addHeader(new BasicHeader(key, header.get(key)));
                }
            }
            //创建参数列表
            List<BasicNameValuePair> params = new ArrayList<>();
            for (String key : param.keySet()) {
                params.add(new BasicNameValuePair(key, param.get(key).toString()));
            }
            //url格式编码
            UrlEncodedFormEntity uefEntity = new UrlEncodedFormEntity(params, "UTF-8");
            post.setEntity(uefEntity);
            //执行请求
            try (CloseableHttpResponse httpResponse = httpClient.execute(post)) {
                HttpEntity entity = httpResponse.getEntity();
                if (null != entity) {
                    result = EntityUtils.toString(entity);
                }
            }

        } catch(IOException e){
            e.printStackTrace();
        } finally{
            try{
                closeHttpClient(httpClient);
            } catch(Exception e){
                e.printStackTrace();
            }
        }
        return result;
    }


    /**
     * PATCH方式发起http请求
     */
    public String sendPatch(String url){return sendPatch(url,null,null);}
    public String sendPatch(String url,Map<String, Object> param){return sendPatch(url,param,null);}
    public String sendPatch(String url, Map<String, Object> param, Map<String, String> header){
        int statusCode = 0;
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpPatch patch = new HttpPatch(url);
        //请求头
        if (header!=null) {
            for (Map.Entry<String, String> entry : header.entrySet()) {
                patch.addHeader(entry.getKey(), entry.getValue());
            }
        }
        patch.setHeader("Content-type", "application/json");
        JSONObject jsonObj=null;
        if (param != null){
            //创建参数列表
            jsonObj=new JSONObject(param);
        }
        try {
            //url格式编码
            assert jsonObj != null;
            StringEntity entity = new StringEntity(jsonObj.toString(), StandardCharsets.UTF_8);
            patch.setEntity(entity);
            HttpResponse response = httpClient.execute(patch);
            statusCode = response.getStatusLine().getStatusCode();
        } catch (IOException e) {
            System.out.println(e.getMessage());
        }finally {
            try {
                httpClient.close();

            } catch (IOException e) {
                System.out.println(e.getMessage());
            }
        }
        return statusCode+"";
    }

    /**
     * Delete方式发起http请求
     */

    public String sendDelete(String url, Map<String,String> header){
        String result = null;
        CloseableHttpClient httpClient = getHttpClient();
        try {
            HttpDelete delete = new HttpDelete(url);
            //添加请求头,和请求体
            if (header != null && header.size() > 0) {
                for (String key : header.keySet()) {
                    delete.addHeader(new BasicHeader(key, header.get(key)));
                }
            }
            //执行请求
            try (CloseableHttpResponse httpResponse = httpClient.execute(delete)) {
                HttpEntity entity = httpResponse.getEntity();
                if (null == entity) {
                    result="";
                }else result = EntityUtils.toString(entity);
            }

        } catch(IOException e){
            e.printStackTrace();
        } finally{
            try{
                closeHttpClient(httpClient);
            } catch(Exception e){
                e.printStackTrace();
            }
        }
        return result;
    }
    //功能函数
    private CloseableHttpClient getHttpClient(){
        return HttpClientBuilder.create().build();
    }

    private void closeHttpClient(CloseableHttpClient client) throws IOException{
        if (client != null){
            client.close();
        }
    }
}